//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include <Core/Core.hpp>
#include "Item.hpp"
#include "TypedItem.hpp"


namespace Config
{
	class InitializerList
	{
	public:
		// Construction.
		template< typename Type >
		InitializerList( const std::string& key, Type& tp );
		template< typename Type >
		InitializerList( const InitializerList& rhs, Type& tp );
		~InitializerList();

		// Item interface.
		InitializerList*			Prev() const;
		InitializerList*			Next() const;
		Config::Item*				Item() const;

		// Static interface.
		static InitializerList*		First();
		static Config::Item*		Find( const std::string& name );

	private:
		// Implementation members.
		void						_Initialize();
		void						_Store();

		// Implementation data.
		Config::Item*				mpItem;
		InitializerList*			mpPrev;
		InitializerList*			mpNext;
		static InitializerList*		mpFirst;
	};


	//////////////////////////////////////////////////////////////////////////
	template< typename Type >
	InitializerList::InitializerList( const std::string& key, Type& tp )
	:	mpItem( new TypedItem< Type >( key, tp ) )
	,	mpPrev( nullptr )
	,	mpNext( mpFirst )
	{
		if( mpFirst )
			mpFirst->mpPrev	=	this;
		mpFirst			=	this;

		_Initialize();
	}

	template< typename Type >
	InitializerList::InitializerList( const InitializerList& rhs, Type& tp )
	:	mpItem( new TypedItem< Type >( tp, *(Config::TypedItem< Type >*)rhs.mpItem ) )
	,	mpPrev( nullptr )
	,	mpNext( mpFirst )
	{
		if( mpFirst )
			mpFirst->mpPrev	=	this;
		mpFirst			=	this;

		_Initialize();
	}
}
